#include <Arduino.h>
#include <FastLED.h>

// 灯珠数
#define LED_NUMS 24

// 引脚定义
#define CLR_PIN 2
#define BRG_PIN 3
#define MOD_PIN 4
#define DATA_PIN 5

// 颜色枚举
enum ledColor
{
    led_clr1_WHT = 0,
    led_clr1_RED,
    led_clr1_GRN,
    led_clr1_BLU,
    led_clr1_RnB,
    led_clr1_END
};

// 模式枚举
enum ledMode
{
    LED_MODE_SOLID = 0, // 单色模式
    LED_MODE_BLINK,     // 闪烁模式
    LED_MODE_BRTH,      // 呼吸模式
    LED_MODE_SOS,       // SOS闪烁
    LED_MODE_RB,        // 彩虹模式
    LED_MODE_RB_WF,     // 彩虹流水模式
    LED_MODE_GR,        // 渐变模式
    LED_MODE_OFF,       // 关闭
    LED_MODE_END
};

byte glb_brightness = 20;
byte glb_color_sta = 0;
byte glb_mode_sta = 0;
byte glb_loop_delay = 50;

// Define the array of leds
CRGB leds[LED_NUMS]; // 建立光带leds

void setup()
{
    Serial.begin(115200);
    pinMode(BRG_PIN, INPUT);
    pinMode(CLR_PIN, INPUT);
    pinMode(MOD_PIN, INPUT);
    digitalWrite(BRG_PIN, HIGH);
    digitalWrite(CLR_PIN, HIGH);
    digitalWrite(MOD_PIN, HIGH);

    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, LED_NUMS);
    FastLED.setBrightness(glb_brightness);

    fill_solid(leds, LED_NUMS, CRGB::Black);
    FastLED.show();
}

#define BTN_DELAY 50 // 按钮检测时间
bool btnPressed(byte btnPin)
{
    if (digitalRead(btnPin) == LOW)
    {
        delay(BTN_DELAY);
        if (digitalRead(btnPin) == LOW)
            return true;
    }
    return false;
}

int glb_index = 0;
byte glb_breath = HIGH;
void loop()
{
    // 亮度调节
    if (btnPressed(BRG_PIN))
    {
        glb_brightness = glb_brightness + 5;
        if (glb_brightness >= 255)
        {
            glb_brightness = 5;
        }
    }

    // 单切换颜色(solid模式)
    if (btnPressed(CLR_PIN))
    {
        glb_color_sta++;
        if (glb_color_sta >= led_clr1_END)
            glb_color_sta = 0;
    }

    Serial.print("Brightness: ");
    Serial.print(glb_brightness);
    Serial.print(", Color: ");
    Serial.print(glb_color_sta);
    Serial.print(", Mode: ");
    Serial.println(glb_mode_sta);

    CRGB led_clr1 = CRGB::White;
    CRGB led_clr2 = CRGB::Red;
    switch (glb_color_sta)
    {
    case led_clr1_WHT:
        led_clr1 = CRGB::White;
        led_clr2 = CRGB::Red;
        break;
    case led_clr1_RED:
        led_clr1 = CRGB::Red;
        led_clr2 = CRGB::Green;
        break;
    case led_clr1_GRN:
        led_clr1 = CRGB::Green;
        led_clr2 = CRGB::Blue;
        break;
    case led_clr1_BLU:
        led_clr1 = CRGB::Blue;
        led_clr2 = CRGB::White;
        break;
    case led_clr1_RnB:
        led_clr1 = CRGB::Blue;
        led_clr2 = CRGB::Red;
        break;
    default:
        break;
    }

    // 模式切换
    if (btnPressed(MOD_PIN))
    {
        glb_index = 0;
        glb_mode_sta++;
        if (glb_mode_sta == LED_MODE_END)
            glb_mode_sta = LED_MODE_SOLID;
    }

    int deltaBrgh = 5;
    switch (glb_mode_sta)
    {
    case LED_MODE_SOLID:
        if (glb_color_sta == led_clr1_RnB)
        {
            fill_solid(leds + 0, LED_NUMS / 2, led_clr1);
            fill_solid(leds + 12, LED_NUMS / 2, led_clr2);
        }
        else
            fill_solid(leds, LED_NUMS, led_clr1);

        break;
    case LED_MODE_BRTH:
        fill_solid(leds, LED_NUMS, led_clr1);
        if (glb_breath == LOW)
            deltaBrgh = -15;
        else
            deltaBrgh = 5;

        glb_brightness += deltaBrgh;
        if (glb_brightness >= 255)
            glb_breath = LOW;
        if (glb_brightness <= 0)
            glb_breath = HIGH;
        break;

    case LED_MODE_BLINK:
        if (glb_index < 10)
            fill_solid(leds, LED_NUMS, led_clr1);
        else if (glb_index >= 10 && glb_index < 20)
            fill_solid(leds, LED_NUMS, CRGB::Black);
        else
            glb_index = 0;
        break;

    case LED_MODE_SOS:
        if ((glb_index >= 0 && glb_index < 10) ||
            (glb_index >= 20 && glb_index < 30) ||
            (glb_index >= 40 && glb_index < 50) ||
            (glb_index >= 60 && glb_index < 90) ||
            (glb_index >= 100 && glb_index < 130) ||
            (glb_index >= 140 && glb_index < 170) ||
            (glb_index >= 180 && glb_index < 190) ||
            (glb_index >= 200 && glb_index < 210) ||
            (glb_index >= 220 && glb_index < 230))
            fill_solid(leds, LED_NUMS, led_clr1);
        else if ((glb_index >= 10 && glb_index < 20) ||
                 (glb_index >= 30 && glb_index < 40) ||
                 (glb_index >= 50 && glb_index < 60) ||
                 (glb_index >= 90 && glb_index < 100) ||
                 (glb_index >= 130 && glb_index < 140) ||
                 (glb_index >= 170 && glb_index < 180) ||
                 (glb_index >= 190 && glb_index < 200) ||
                 (glb_index >= 210 && glb_index < 220) ||
                 (glb_index >= 230 && glb_index < 260))
            fill_solid(leds, LED_NUMS, CRGB::Black);
        else
            glb_index = 0;

        break;
    case LED_MODE_RB: // 彩虹
        fill_rainbow_circular(leds, LED_NUMS, 0);
        break;
    case LED_MODE_RB_WF: // 彩虹流水
        int initHue = int(glb_index * 3);
        if (initHue >= 255)
            glb_index = 0;
        fill_rainbow_circular(leds, LED_NUMS, initHue);
        break;
    case LED_MODE_GR: // 渐变
        fill_gradient_RGB(leds, LED_NUMS, led_clr1, led_clr2);
        break;
    case LED_MODE_OFF: // 关闭
        fill_solid(leds, LED_NUMS, CRGB::Black);
        break;
    case LED_MODE_END:
        glb_mode_sta = LED_MODE_SOLID;
        break;
    default:
        break;
    }

    FastLED.setBrightness(glb_brightness);
    FastLED.show();

    delay(glb_loop_delay);
    glb_index++;
}
